package com.view;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.text.DefaultCaret;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

import com.model.logic.*;
import com.model.objects.Crocodile;
import com.model.objects.Fox;
import com.model.objects.Rabbit;
import com.controller.*;
import com.view.PieChart;


/**
 * A graphical view of the simulation grid.
 * The view displays a colored rectangle for each location 
 * representing its contents. It uses a default background color.
 * Colors for each type of species can be defined using the
 * setColor method.
 * 
 * @author Hofsep, Michiel, Bakr
 * @version 08.02.2013
 */
public class SimulatorView extends JFrame {

	private static final long serialVersionUID = 277424818342055257L;

	// Colors used for empty locations.
	private static final Color EMPTY_COLOR1 = Color.green;

	// Color used for objects that have no defined color.
	private static final Color UNKNOWN_COLOR = Color.gray;

	private final String STEP_PREFIX = "Step: ";
	private final String POPULATION_PREFIX = "Population: ";
	private JLabel stepLabel, population;

	// view instanties
	private FieldView fieldView;
	private PieChart pieChart;
	private Histogram histogram;
	private HistoryView historyView;

	private FieldStats stats;
	
	private static JFrame settingsFrame;
	
	//recente zichtbare velden
	protected static JLabel rabbitCreationProbabilityLabel;
	protected static JLabel foxCreationProbabilityLabel;
	protected static JLabel crocodileCreationProbabilityLabel;
	protected static JLabel jagerCreationProbabilityLabel;
	
	protected static JLabel rabbitBreedingAgeLabel;
	protected static JLabel rabbitMaxAgeLabel;
	protected static JLabel rabbitBreedingProbabilityLabel;
	protected static JLabel rabbitMaxLitterSizeLabel;
	
	protected static JLabel foxBreedingAgeLabel;
	protected static JLabel foxMaxAgeLabel;
	protected static JLabel foxBreedingProbabilityLabel;
	protected static JLabel foxMaxLitterSizeLabel;
	
	protected static JLabel crocodileBreedingAgeLabel;
	protected static JLabel crocodileMaxAgeLabel;
	protected static JLabel crocodileBreedingProbabilityLabel;
	protected static JLabel crocodileMaxLitterSizeLabel;
	

	// een map om alle kleuren op te slaan
	@SuppressWarnings("rawtypes")
	private Map<Class, Color> colors;
	
	private boolean isReset;
	private Simulator simulator;
	private static final String VERSION = "versie 0.0";

	/**
	 * Create a view of the given width and height.
	 * 
	 * @param height
	 *            The simulation's height.
	 * @param width
	 *            The simulation's width.
	 */
	@SuppressWarnings("rawtypes")
	public SimulatorView(int height, int width, Simulator s) {
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

		stats = new FieldStats();
		colors = new LinkedHashMap<Class, Color>();
		simulator = s;

		makeFieldView(height, width);
		makePieChart(height, width);
		makeHistogram(height, width);
		makeHistoryView(height, width);

		makeMainFrame();
		makeMenuBar();
		setTitle("Fox and Rabbit Simulation");
	}

	/**
	 * Maak main frame aan en al zijn componenten Main frame is de onderste
	 * laag, daarna komt tweede laag view panel (rechterkant) en toolbar panel
	 * (linkerkant). Aan de toolbar panel worden knoppen toegevoegd en aan de
	 * view panel worden meerdere views toegevoegd(piecharts etc.)
	 */
	public void makeMainFrame() {
		// maak main frame (onderste laag) aan, layout en border van main frame.
		JPanel mainFrame = new JPanel();
		mainFrame.setLayout(new BorderLayout());
		mainFrame.setBorder(new EmptyBorder(10, 10, 10, 10));

		// maak view panel (tweede laag) aan, layout en border van view panel.
		JPanel viewPanel = new JPanel();
		viewPanel.setLayout(new GridLayout(2, 2));
		viewPanel.setBorder(new EmptyBorder(5, 5, 5, 5));
		
		// maak field panel (bovenste laag) aan, en border van field panel.
		JPanel field = new JPanel();
		field.setLayout(new BorderLayout());
		field.add(stepLabel, BorderLayout.NORTH);
		field.add(fieldView, BorderLayout.CENTER);
		field.add(population, BorderLayout.SOUTH);
		
		// maak toolbar panel (tweede laag, linkerkant) aan, layout en border
		// van toolbar panel
		JPanel toolbar = new JPanel();
		toolbar.setLayout(new GridLayout(20, 0));
		toolbar.setBorder(new EmptyBorder(20, 10, 20, 10));
	
		// labels en knoppen
		// voeg ActionListener voor ieder knop en voeg het toe aan toolbar panel
		JButton step1 = new JButton("Step 1");
		JButton step100 = new JButton("Step 100");		
		JButton start = new JButton("Start");
		JButton stop = new JButton("Stop");		
		JButton reset = new JButton("Reset");
		JButton lava = new JButton("Simulate Volcano");
		
		
		step1.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) {
														simulator.simulateOneStep();}
														});
		
		step100.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
														simulator.simulate(100);}
														});

		start.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
														simulator.start();
														Component c = (Component)e.getSource(); 
														c.getToolkit().beep();}
														});
		
		stop.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
														simulator.stopRun();
														Component c = (Component)e.getSource(); 
														c.getToolkit().beep();}
														});
		
		reset.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
														historyView.setStep(0);
														simulator.reset();}
														});
		
        lava.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) { 
        												simulator.startLava(); }
        											});
		
		toolbar.add(step1);		
		toolbar.add(step100);
		toolbar.add(start);
		toolbar.add(stop);
		toolbar.add(reset);
        toolbar.add(lava);
		
		// pieChart panel
		JPanel chart = new JPanel();
		chart.setLayout(new BorderLayout());
		chart.add(pieChart, BorderLayout.CENTER);

		// histoGram panel
		JPanel diagram = new JPanel();
		diagram.setLayout(new BorderLayout());
		diagram.add(histogram, BorderLayout.CENTER);
		
		// textArea panel
		JTextArea textArea = new JTextArea(20, 20);
		historyView.setTextArea(textArea);	
		
		// scroll panel voor de textArea
		JScrollPane scrollPane = new JScrollPane(textArea);
		DefaultCaret caret = (DefaultCaret) textArea.getCaret();
		caret.setUpdatePolicy(DefaultCaret.ALWAYS_UPDATE);
		textArea.setEditable(false);
		scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);		
		
		// maak een balk met versie nummer onderaan de frame en voeg toe aan de
		// main frame
		JLabel statusLabel = new JLabel(VERSION);
		mainFrame.add(statusLabel, BorderLayout.SOUTH);

		//	alles toevoegen aan de frame
		this.add(mainFrame);
		mainFrame.add(viewPanel, BorderLayout.CENTER); 
		mainFrame.add(toolbar, BorderLayout.WEST);
		
		viewPanel.add(field);
		viewPanel.add(chart);
		viewPanel.add(diagram);
		viewPanel.add(scrollPane);
		
		// Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
		setSize(new Dimension(1280, 720));
		setLocationRelativeTo(null);
		setResizable(false);
		setVisible(true);
	}
	
	/**
	 * Maak de hoofdmenu aan
	 */
	public void makeMenuBar() {
		// shorcuts kits
		final int SHORTCUT_MASK = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask();

		// maak een menubalk aan.
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		
		// maak de menu en menu items aan
		JMenu menu;
		JMenuItem item;

		// maak menu file aan
		menu = new JMenu("File");
		menuBar.add(menu);

		// maak menu item settings aan en ActionListener
		item = new JMenuItem("Settings");
		item.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
														if (settingsFrame == null){
															makeSettings();
														}
														settingsFrame.setVisible(true);}
													});
		menu.add(item);
		menu.addSeparator();

		// maak menu item quit aan
		item = new JMenuItem("Quit");
		item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, SHORTCUT_MASK));
		
		item.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
														quit();}
													});
		menu.add(item);

		//	maak help menu aan
		menu = new JMenu("Help");
		menuBar.add(menu);
	}
	
	/**
	 * maak een pop up settings window, wordt opgeroepen wanneer menu item
	 * settings wordt gebruikt. Settings wordt gebruikt om gegevens van een
	 * actoren te kunnen wijzigen
	 */
	public static void makeSettings() {

		//	maak settings frame aan
		settingsFrame = new JFrame();
		settingsFrame.setTitle("Settings");
		
		//	maak settings frame's main tab aan, size, layout en border van
		//	settings panel
		JTabbedPane mainTab = new JTabbedPane();
		mainTab.setBorder(new EmptyBorder(10, 10, 10, 10));
		mainTab.setPreferredSize(new Dimension(100, 100));

		//	maak general tab aan, layout en border
		JPanel generalTab = new JPanel();
		generalTab.setLayout(new GridLayout(0, 3));
		generalTab.setBorder(new EmptyBorder(10, 10, 10, 10));
		
		//	voeg labels, tekstvelden toe aan general tab		
		generalTab.add(new JLabel("Rabbit creation probability"));
		final JTextField rabbitCreationProbability = new JTextField();
		generalTab.add(rabbitCreationProbability);
		rabbitCreationProbabilityLabel = new JLabel(Simulator.getRabbitCreationProbability());
		generalTab.add(rabbitCreationProbabilityLabel);
		
		generalTab.add(new JLabel("Fox creation probability"));
		final JTextField foxCreationProbability = new JTextField();
		generalTab.add(foxCreationProbability);
		foxCreationProbabilityLabel = new JLabel(Simulator.getFoxCreationProbability());
		generalTab.add(foxCreationProbabilityLabel);
		
		generalTab.add(new JLabel("Crocodile creation probability"));
		final JTextField crocodileCreationProbability = new JTextField();
		generalTab.add(crocodileCreationProbability);		
		crocodileCreationProbabilityLabel = new JLabel(Simulator.getCrocodileCreationProbability());
		generalTab.add(crocodileCreationProbabilityLabel);
		
		generalTab.add(new JLabel("Jager creation probability"));
		final JTextField jagerCreationProbability = new JTextField();
		generalTab.add(jagerCreationProbability);
		jagerCreationProbabilityLabel = new JLabel(Simulator.getJagerCreationProbability());
		generalTab.add(jagerCreationProbabilityLabel);
		
		// change setting button
		JButton change = new JButton("change setting");
		change.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {
			
				if(!(rabbitCreationProbability.getText().equals("") && foxCreationProbability.getText().equals("") && crocodileCreationProbability.getText().equals("") && jagerCreationProbability.getText().equals(""))){
					Simulator.setRabbitCreationProbability(Double.parseDouble(rabbitCreationProbability.getText()));
					rabbitCreationProbabilityLabel.setText(Simulator.getRabbitCreationProbability());

					Simulator.setFoxCreationProbability(Double.parseDouble(foxCreationProbability.getText()));	
					foxCreationProbabilityLabel.setText(Simulator.getFoxCreationProbability());

					Simulator.setCrocodileCreationProbability(Double.parseDouble(crocodileCreationProbability.getText()));
					crocodileCreationProbabilityLabel.setText(Simulator.getCrocodileCreationProbability());

					Simulator.setJagerCreationProbability(Double.parseDouble(jagerCreationProbability.getText()));
					jagerCreationProbabilityLabel.setText(Simulator.getJagerCreationProbability());
				}		
				else {
					JOptionPane.showMessageDialog(null, "U heeft niks ingevuld.");
				}
			}			
		});
		generalTab.add(change);
		
		//	set default button
		JButton setDefault = new JButton("default");
		setDefault.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Simulator.setDefault();
				rabbitCreationProbabilityLabel.setText(Simulator.getRabbitCreationProbability());
				foxCreationProbabilityLabel.setText(Simulator.getFoxCreationProbability());
				crocodileCreationProbabilityLabel.setText(Simulator.getCrocodileCreationProbability());
				jagerCreationProbabilityLabel.setText(Simulator.getJagerCreationProbability());			
			}});
		generalTab.add(setDefault);
			
		// maak rabbits tab aan, layout en border
		JPanel rabbitTab = new JPanel();
		rabbitTab.setLayout(new GridLayout(0, 3));
		rabbitTab.setBorder(new EmptyBorder(10, 10, 10, 10));

		// voeg labels, tekstvelden en ActionListener toe aan rabbit tab
		rabbitTab.add(new JLabel("Breeding age"));
		final JTextField rabbitBreedingAge = new JTextField();
		rabbitTab.add(rabbitBreedingAge);
		rabbitBreedingAgeLabel = new JLabel(Rabbit.getBreedingAge());
		rabbitTab.add(rabbitBreedingAgeLabel);
		
		rabbitTab.add(new JLabel("Max age"));
		final JTextField rabbitMaxAge = new JTextField();
		rabbitTab.add(rabbitMaxAge);
		rabbitMaxAgeLabel = new JLabel(Rabbit.getMaxAge());
		rabbitTab.add(rabbitMaxAgeLabel);
		
		rabbitTab.add(new JLabel("Breeding probability"));
		final JTextField rabbitBreedingProbability = new JTextField();
		rabbitTab.add(rabbitBreedingProbability);
		rabbitBreedingProbabilityLabel = new JLabel(Rabbit.getBreedingProbablity());
		rabbitTab.add(rabbitBreedingProbabilityLabel);
		
		rabbitTab.add(new JLabel("Max litter size"));
		final JTextField rabbitMaxLitterSize = new JTextField();
		rabbitTab.add(rabbitMaxLitterSize);
		rabbitMaxLitterSizeLabel = new JLabel(Rabbit.getMaxLitterSize());
		rabbitTab.add(rabbitMaxLitterSizeLabel);
		
		// change setting button
		JButton changeRabbit = new JButton("change setting");
		changeRabbit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(!(rabbitBreedingAge.getText().equals("") && rabbitMaxAge.getText().equals("") && rabbitBreedingProbability.getText().equals("") && rabbitMaxLitterSize.getText().equals("")))
				{
					Rabbit.setBreedingAge(Integer.parseInt(rabbitBreedingAge.getText()));
					rabbitBreedingAgeLabel.setText(Rabbit.getBreedingAge());

					Rabbit.setMaxAge(Integer.parseInt(rabbitMaxAge.getText()));
					rabbitMaxAgeLabel.setText(Rabbit.getMaxAge());

					Rabbit.setBreedingProbability(Double.parseDouble(rabbitBreedingProbability.getText()));
					rabbitBreedingProbabilityLabel.setText(Rabbit.getBreedingProbablity());

					Rabbit.setMaxLitterSize(Integer.parseInt(rabbitMaxLitterSize.getText()));
					rabbitMaxLitterSizeLabel.setText(Rabbit.getMaxLitterSize());
				}
				else {
					JOptionPane.showMessageDialog(null, "U heeft niks ingevuld.");
				}
			}			
		});
		rabbitTab.add(changeRabbit);
		
		//	set default button
		JButton setDefaultRabbit = new JButton("default");
		setDefaultRabbit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Rabbit.setDefault();
				rabbitBreedingAgeLabel.setText(Rabbit.getBreedingAge());
				rabbitMaxAgeLabel.setText(Rabbit.getMaxAge());
				rabbitBreedingProbabilityLabel.setText(Rabbit.getBreedingProbablity());
				rabbitMaxLitterSizeLabel.setText(Rabbit.getMaxLitterSize());
			}
		});
		rabbitTab.add(setDefaultRabbit);

		// maak foxes tab aan, layout en border
		JPanel foxTab = new JPanel();
		foxTab.setLayout(new GridLayout(0, 3));
		foxTab.setBorder(new EmptyBorder(10, 10, 10, 10));

		// voeg labels, tekstvelden en ActionListener toe aan fox tab
		foxTab.add(new JLabel("Breeding age"));
		final JTextField foxBreedingAge = new JTextField();
		foxTab.add(foxBreedingAge);
		foxBreedingAgeLabel = new JLabel(Fox.getBreedingAge());
		foxTab.add(foxBreedingAgeLabel);
		
		foxTab.add(new JLabel("Max age"));
		final JTextField foxMaxAge = new JTextField();
		foxTab.add(foxMaxAge);
		foxMaxAgeLabel = new JLabel(Fox.getMaxAge());
		foxTab.add(foxMaxAgeLabel);
		
		foxTab.add(new JLabel("Breeding probability"));
		final JTextField foxBreedingProbability = new JTextField();
		foxTab.add(foxBreedingProbability);
		foxBreedingProbabilityLabel = new JLabel(Fox.getBreedingAge());
		foxTab.add(foxBreedingProbabilityLabel);
		
		foxTab.add(new JLabel("Max litter size"));
		final JTextField foxMaxLitterSize = new JTextField();
		foxTab.add(foxMaxLitterSize);
		foxMaxLitterSizeLabel = new JLabel(Fox.getMaxLitterSize());
		foxTab.add(foxMaxLitterSizeLabel);
		
		// change setting button
		JButton changeFox = new JButton("change setting");
		changeFox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(!(foxBreedingAge.getText().equals("") && foxMaxAge.getText().equals("") && foxBreedingProbability.getText().equals("") && foxMaxLitterSize.getText().equals(""))){
					Fox.setBreedingAge(Integer.parseInt(foxBreedingAge.getText()));
					foxMaxLitterSizeLabel.setText(Fox.getMaxLitterSize());

					Fox.setMaxAge(Integer.parseInt(foxMaxAge.getText()));	
					foxMaxAgeLabel.setText(Fox.getMaxAge());

					Fox.setBreedingProbability(Double.parseDouble(foxBreedingProbability.getText()));
					foxBreedingProbabilityLabel.setText(Fox.getBreedingProbablity());

					Fox.setMaxLitterSize(Integer.parseInt(foxMaxLitterSize.getText()));	
					foxMaxLitterSizeLabel.setText(Fox.getMaxLitterSize());
				}	
				else {
					JOptionPane.showMessageDialog(null, "U heeft niks ingevuld.");
				}
			}			
		});
		foxTab.add(changeFox);
		
		//	set default button
		JButton setDefaultFox = new JButton("default");
		setDefaultFox.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Fox.setDefault();
				foxMaxLitterSizeLabel.setText(Fox.getMaxLitterSize());
				foxMaxAgeLabel.setText(Fox.getMaxAge());
				foxBreedingProbabilityLabel.setText(Fox.getBreedingProbablity());
				foxMaxLitterSizeLabel.setText(Fox.getMaxLitterSize());
			}
		});
		foxTab.add(setDefaultFox);
		
		// maak crocodile tab aan, layout en border
		JPanel crocodileTab = new JPanel();
		crocodileTab.setLayout(new GridLayout(0, 3));
		crocodileTab.setBorder(new EmptyBorder(10, 10, 10, 10));

		// voeg labels, tekstvelden en ActionListener toe aan crocodile tab
		crocodileTab.add(new JLabel("Breeding age"));
		final JTextField crocodileBreedingAge = new JTextField();
		crocodileTab.add(crocodileBreedingAge);
		crocodileBreedingAgeLabel = new JLabel(Crocodile.getBreedingAge());
		crocodileTab.add(crocodileBreedingAgeLabel);
		
		crocodileTab.add(new JLabel("Max age"));
		final JTextField crocodileMaxAge = new JTextField();
		crocodileTab.add(crocodileMaxAge);
		crocodileMaxAgeLabel = new JLabel(Crocodile.getMaxAge());
		crocodileTab.add(crocodileMaxAgeLabel);
		
		crocodileTab.add(new JLabel("Breeding probability"));
		final JTextField crocodileBreedingProbability = new JTextField();
		crocodileTab.add(crocodileBreedingProbability);
		crocodileBreedingProbabilityLabel = new JLabel(Crocodile.getBreedingProbablity());
		crocodileTab.add(crocodileBreedingProbabilityLabel);
		
		crocodileTab.add(new JLabel("Max litter size"));
		final JTextField crocodileMaxLitterSize = new JTextField();
		crocodileTab.add(crocodileMaxLitterSize);
		crocodileMaxLitterSizeLabel = new JLabel(Crocodile.getMaxLitterSize());
		crocodileTab.add(crocodileMaxLitterSizeLabel);
		
		// change setting button
		JButton changeCrocodile = new JButton("change setting");
		changeCrocodile.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(!(crocodileBreedingAge.getText().equals("") && crocodileMaxAge.getText().equals("") && crocodileBreedingProbability.getText().equals("") && crocodileMaxLitterSize.getText().equals(""))){
					Crocodile.setBreedingAge(Integer.parseInt(crocodileBreedingAge.getText()));
					crocodileBreedingAgeLabel.setText(Crocodile.getBreedingAge());

					Crocodile.setMaxAge(Integer.parseInt(crocodileMaxAge.getText()));
					crocodileMaxAgeLabel.setText(Crocodile.getMaxAge());

					Crocodile.setBreedingProbability(Double.parseDouble(crocodileBreedingProbability.getText()));
					crocodileBreedingProbabilityLabel.setText(Crocodile.getBreedingProbablity());

					Crocodile.setMaxLitterSize(Integer.parseInt(crocodileMaxLitterSize.getText()));	
					crocodileMaxLitterSizeLabel.setText(Crocodile.getMaxLitterSize());
				}
				else {
					JOptionPane.showMessageDialog(null, "U heeft niks ingevuld.");
				}
			}
		});
		crocodileTab.add(changeCrocodile);
		
		//	set default button
		JButton setDefaultCrocodile = new JButton("default");
		setDefaultCrocodile.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Crocodile.setDefault();
				crocodileBreedingAgeLabel.setText(Crocodile.getBreedingAge());
				crocodileMaxAgeLabel.setText(Crocodile.getMaxAge());
				crocodileBreedingProbabilityLabel.setText(Crocodile.getBreedingProbablity());
				crocodileMaxLitterSizeLabel.setText(Crocodile.getMaxLitterSize());
			}
		});
		crocodileTab.add(setDefaultCrocodile);	
		
		// alle tabs toevoegen aan maintab
		// main tab toevoegen aan de settings frame
		mainTab.addTab("General", generalTab);
		mainTab.addTab("Rabbit", rabbitTab);
		mainTab.addTab("Fox", foxTab);
		mainTab.addTab("Crocodile", crocodileTab);
//		mainTab.addTab("Jager", jagerTab);		
		
		
		settingsFrame.add(mainTab);

		settingsFrame.setSize(new Dimension(640, 240));

		settingsFrame.setResizable(false);
		settingsFrame.setLocationRelativeTo(null); // center de settingsFrame
		settingsFrame.setVisible(true);
	}
	
	/**
	 * Quit menu om het programma af te sluiten.
	 */
	public static void quit() {
		System.exit(0);
	}

	/**
	 * maak fieldView aan
	 * @param height
	 * @param width
	 */
	public void makeFieldView(int height, int width) {
		fieldView = new FieldView(height, width);
		stepLabel = new JLabel(STEP_PREFIX, JLabel.CENTER);
		population = new JLabel(POPULATION_PREFIX, JLabel.CENTER);
	}

	/**
	 * maak pieChart aan
	 * @param height
	 * @param width
	 */
	private void makePieChart(int height, int width) {
		pieChart = new PieChart();
		pieChart.setSize(height * 2, width * 2);
		pieChart.stats(getPopulationDetails());
		pieChart.repaint();
	}

	/**
	 * maak histogram aan
	 * @param height
	 * @param width
	 */
	private void makeHistogram(int height, int width) {
		histogram = new Histogram();
		histogram.setSize(height * 2, width * 2);
		histogram.stats(getPopulationDetails());
		histogram.repaint();
	}

	/**
	 * maak historyView aan
	 * @param height
	 * @param width
	 */
	private void makeHistoryView(int height, int width) {
		historyView = new HistoryView(height, width);
		historyView.setSize(height, width);
		historyView.stats(getPopulationDetails());
		historyView.history(getIsReset());
	}

	/**
	 * getter voor FieldStats stats
	 * @param stats
	 */
	public FieldStats getStats() {
		return stats;
	}

	/**
	 * Getter voor boolean isReset
	 * @return isReset bepaald of step 0 is voor de historyview
	 */
	public boolean getIsReset() {
		return isReset;
	}

	/**
	 * Define a color to be used for a given class of animal.
	 * 
	 * @param animalClass
	 *            The animal's Class object.
	 * @param color
	 *            The color to be used for the given class.
	 */
	@SuppressWarnings("rawtypes")
	public void setColor(Class animalClass, Color color) {
		colors.put(animalClass, color);
	}

	/**
	 * @return The color to be used for a given class of animal.
	 */
	@SuppressWarnings("rawtypes")
	private Color getColor(Class animalClass) {
		Color col = colors.get(animalClass);
		if (col == null) {
			// no color defined for this class
			return UNKNOWN_COLOR;
		} else {
			return col;
		}
	}
	
	/**
	 * Show the current status of the field.
	 * 
	 * @param step
	 *            Which iteration step it is.
	 * @param field
	 *            The field whose status is to be displayed.
	 */
	public void showStatus(int step, Field field) {
		if (!isVisible()) {
			setVisible(true);
		}

		stepLabel.setText(STEP_PREFIX + step);
		stats.reset();

		fieldView.preparePaint();

		for (int row = 0; row < field.getDepth(); row++) {
			for (int col = 0; col < field.getWidth(); col++) {
				Object animal = field.getObjectAt(row, col);
				if (animal != null) {
					stats.incrementCount(animal.getClass());
					fieldView.drawMark(col, row, getColor(animal.getClass()));
				} else {
					fieldView.drawMark(col, row, EMPTY_COLOR1);
				}
			}
		}
		stats.countFinished();

		population.setText(POPULATION_PREFIX
				+ stats.getPopulationDetails(field));
		fieldView.repaint();

		pieChart.stats(getPopulationDetails());
		pieChart.repaint();

		histogram.stats(getPopulationDetails());
		histogram.repaint();

		historyView.stats(getPopulationDetails());
		historyView.history(getIsReset());
	}

	/**
	 * retourneert de counter voor ieder kleur 
	 * @return colorStats HashMap die kleur bij houdt en de hoeveelheid
	 */
	@SuppressWarnings("rawtypes")
	public HashMap<Color, Counter> getPopulationDetails() {
		HashMap<Class, Counter> classStats = stats.getPopulation();
		HashMap<Color, Counter> colorStats = new HashMap<Color, Counter>();

		for (Class c : classStats.keySet()) {
			colorStats.put(getColor(c), classStats.get(c));
		}
		return colorStats;
	}

	/**
	 * retourneert de counter voor ieder kleur
	 * @return classStats HashMap die class bij hout en de hoeveelheid
	 */
	@SuppressWarnings("rawtypes")
	public HashMap<Class, Counter> getPopulationDetails2() {
		HashMap<Class, Counter> classStats = stats.getPopulation();
		return classStats;
	}
	
	/**
	 * Determine whether the simulation should continue to run.
	 * 
	 * @return true If there is more than one species alive.
	 */
	public boolean isViable(Field field) {
		return stats.isViable(field);
	}
	
    public Simulator getSim()
    {
    	return this.simulator;
    }
}
